package com.shaozi.nc.manage.observer.manage;

import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.shaozi.common.schedule.DyncQuartzManage;
import com.shaozi.data.mq.business.observer.MqTargetObserverBean;
import com.shaozi.lib.throwable.SzException;
import com.shaozi.nc.consts.SCConsts;
import com.shaozi.nc.consts.SCConsts.QuartzKey;
import com.shaozi.nc.data.hibVO.ReportVO;
import com.shaozi.nc.hibservice.ReportService;
import com.shaozi.nc.mq.bean.report.RuleUpdateBean;
import com.shaozi.nc.quartz.manage.ReportManage;
import com.shaozi.nc.quartz.workreport.ReportJobExecute;

@Service
public class ReportRuleManage {

	private Logger logger = Logger.getLogger(ReportRuleManage.class);

	@Autowired
	private DyncQuartzManage dyncQuartzMgr;
	@Autowired
	private ReportService reportService;
	@Autowired
	private ReportManage reportManage;

	private long alarmTime;
	private Integer alarmType = null;

	public void updateRule2Job(MqTargetObserverBean mqBean, RuleUpdateBean obj) {
		String companyId = mqBean.getCompanyId();
		if (StringUtils.isEmpty(companyId))
			return;
		Integer[] toUserIds = obj.getToUserIds();
		Integer[] deleteUserIds = obj.getDeleteUserIds();
		// 汇报变更人
		if (istrue(toUserIds)) {
			try {
				toUserIds(companyId, toUserIds, deleteUserIds, obj.getType());
			} catch (SchedulerException | SzException e) {
				e.printStackTrace();
				logger.error(e);
			}
			return;
		}
		Integer[] addUserIds = obj.getAddUserIds();
		// 原来不需要写汇报，后来需要写
		if (istrue(addUserIds)) {
			try {
				addUserIds(companyId, addUserIds);
			} catch (SchedulerException | SzException e) {
				e.printStackTrace();
				logger.error(e);
			}
		}
		// 原来需要写汇报，后来不需要写
		if (istrue(deleteUserIds)) {
			try {
				deleteUserIds(companyId, deleteUserIds);
			} catch (SchedulerException | SzException e) {
				e.printStackTrace();
				logger.error(e);
			}
		}
	}

	private void addUserIds(String companyId, Integer[] addUserIds) throws SchedulerException, SzException {
		List<ReportVO> reports = reportService.findByParamsToday(Integer.parseInt(companyId), addUserIds);
		if (reports.isEmpty())
			return;
		for (ReportVO report : reports) {
			String jobName = getJobName(report, companyId, report.getUid());
			if (jobName == null)
				continue;
			String triggerName = String.format("trigger.%s", jobName);

			Map<String, String> dataMap = reportManage.commonDataMap(companyId, alarmType, report, alarmTime);
			// 判断是否存在job
			if (dyncQuartzMgr.existTrigger(QuartzKey.ReportAlarmGroupKey, triggerName))
				continue;
			dyncQuartzMgr.addJobWithOnce(QuartzKey.ReportAlarmGroupKey, jobName, ReportJobExecute.class,
					QuartzKey.ReportAlarmGroupKey, triggerName, alarmTime, dataMap);
		}
	}

	private void deleteUserIds(String companyId, Integer[] deleteUserIds) throws SchedulerException, SzException {
		commonRemoveUid(companyId, deleteUserIds);
	}

	private void toUserIds(String companyId, Integer[] toUserIds, Integer[] deleteUserIds, int type)
			throws SchedulerException, SzException {
		commonRemoveUid(companyId, toUserIds);
		if (istrue(deleteUserIds)) {
			commonRemoveUid(companyId, deleteUserIds);
		}
		reportManage.scheduleByConfig(companyId, true);
	}

	private void commonRemoveUid(String companyId, Integer[] uids) throws SchedulerException, SzException {
		List<ReportVO> reports = reportService.findByParamsToday(Integer.parseInt(companyId), uids);
		if (reports.isEmpty())
			return;
		for (ReportVO report : reports) {
			String jobName = getJobName(report, companyId, report.getUid());
			if (jobName == null)
				continue;
			String triggerName = String.format("trigger.%s", jobName);

			if (!dyncQuartzMgr.existTrigger(QuartzKey.ReportAlarmGroupKey, triggerName))
				continue;
			dyncQuartzMgr.removeJob(QuartzKey.ReportAlarmGroupKey, jobName, QuartzKey.ReportAlarmGroupKey, triggerName);
		}
	}

	private String getJobName(ReportVO report, String companyId, Integer uid) {
		// Integer alarmType = null;
		// long alarmTime =
		report.getRemindStartTime();
		if (alarmTime < System.currentTimeMillis()) {
			alarmTime = report.getRemindEndTime();
			if (!(alarmTime < System.currentTimeMillis())) {
				alarmType = SCConsts.ReportAlarmType.AlarmType_End;
			}
		} else {
			alarmType = SCConsts.ReportAlarmType.AlarmType_Begin;
		}
		if (alarmType == null)
			return null;
		String jobName = String.format("%s.%s.%d.%d.%d", companyId, ReportManage.ALARM, uid, report.getId(), alarmType);
		return jobName;
	}

	private boolean istrue(Integer[] userIds) {
		if (userIds != null && userIds.length > 0) {
			return true;
		} else {
			return false;
		}
	}
}
